From 469c8f8490ad095fea9235a8b162297d7affa593 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sun, 3 Apr 2005 10:11:45 +0000 Subject: [PATCH] bitkeeper revision 1.1236.1.204 (424fc1617oxYkuT_4FpXnRPcprW5ng) Xen fixes and cleanups for x86/64 guests. Signed-off-by: Keir Fraser --- .../i386-xen/include/hypervisor.h | 2 +- .../arch/xen/x86_64/mm/hypervisor.c | 14 ------------ .../include/asm-xen/asm-x86_64/hypercall.h | 5 +---- .../include/asm-xen/asm-x86_64/system.h | 2 +- .../include/asm-xen/hypervisor.h | 2 +- .../sys/arch/xen/include/hypervisor.h | 2 +- xen/arch/x86/domain.c | 8 ++++--- xen/arch/x86/mm.c | 6 ++--- xen/arch/x86/x86_64/entry.S | 7 +++--- xen/arch/x86/x86_64/mm.c | 21 +++++++++++++++++- xen/common/schedule.c | 16 +++++--------- xen/include/public/arch-x86_64.h | 1 + xen/include/public/xen.h | 22 +++++++++---------- 13 files changed, 53 insertions(+), 55 deletions(-) diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h index 95ee85f352..e77f5d6b91 100644 --- a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h +++ b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h @@ -176,7 +176,7 @@ static inline long HYPERVISOR_set_timer_op(uint64_t timeout) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op), - "b" (timeout_hi), "c" (timeout_lo) : "memory" ); + "b" (timeout_lo), "c" (timeout_hi) : "memory" ); return ret; } diff --git a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c index 645420d502..1908dfa478 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c @@ -430,20 +430,6 @@ void xen_tlb_flush(void) spin_unlock_irqrestore(&update_lock, flags); } -void xen_load_gs(unsigned long ptr) -{ - int cpu = smp_processor_id(); - int idx; - unsigned long flags; - spin_lock_irqsave(&update_lock, flags); - idx = per_cpu(mmu_update_queue_idx, cpu); - per_cpu(update_queue[idx], cpu).ptr = phys_to_machine(ptr); - per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND; - per_cpu(update_queue[idx], cpu).val = MMUEXT_LOAD_GS; - increment_index_and_flush(); - spin_unlock_irqrestore(&update_lock, flags); -} - void xen_invlpg(unsigned long ptr) { int cpu = smp_processor_id(); diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h index 0d875a79c2..2055b32c02 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h @@ -218,15 +218,12 @@ static inline long HYPERVISOR_set_timer_op( u64 timeout) { - unsigned long timeout_hi = timeout >> 32; - unsigned long timeout_lo = timeout & 0xffffffff; int ret; __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) - : "0" ((unsigned long)__HYPERVISOR_set_timer_op), - "D" (timeout_hi), "S" (timeout_lo) + : "0" ((unsigned long)__HYPERVISOR_set_timer_op), "D" (timeout) : __syscall_clobber ); return ret; diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/system.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/system.h index 43cae2cc0c..518beb6e39 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/system.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/system.h @@ -55,7 +55,7 @@ extern void load_gs_index(unsigned); #define __load_gs_index(index) \ - xen_load_gs((index)) + HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, index) /* * Load a segment. Fall back on loading the zero diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h index b50c5fc3ad..116e0df853 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h @@ -342,7 +342,7 @@ HYPERVISOR_set_timer_op( __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo) + : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi) : "memory"); return ret; diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h index 2ac01b4d25..d01af8034a 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h @@ -284,7 +284,7 @@ HYPERVISOR_set_timer_op(uint64_t timeout) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo) + : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi) : "memory"); return ret; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 0a599661dc..53d1ea6e3b 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -573,7 +573,7 @@ void new_thread(struct exec_domain *d, void toggle_guest_mode(struct exec_domain *ed) { ed->arch.flags ^= TF_kernel_mode; - __asm__ __volatile__ ( "swapgs" ); + __asm__ __volatile__ ( "mfence; swapgs" ); /* AMD erratum #88 */ update_pagetables(ed); write_ptbase(ed); } @@ -657,7 +657,7 @@ static void load_segments(struct exec_domain *p, struct exec_domain *n) /* If in kernel mode then switch the GS bases around. */ if ( n->arch.flags & TF_kernel_mode ) - __asm__ __volatile__ ( "swapgs" ); + __asm__ __volatile__ ( "mfence; swapgs" ); /* AMD erratum #88 */ if ( unlikely(!all_segs_okay) ) { @@ -711,7 +711,9 @@ static void clear_segments(void) "movl %0,%%ds; " "movl %0,%%es; " "movl %0,%%fs; " - "movl %0,%%gs; swapgs; movl %0,%%gs" + "movl %0,%%gs; " + "mfence; swapgs; " /* AMD erratum #88 */ + "movl %0,%%gs" : : "r" (0) ); } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index d1eb5650b8..aca041e0c6 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2218,8 +2218,7 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries) } -long do_update_descriptor( - unsigned long pa, unsigned long word1, unsigned long word2) +long do_update_descriptor(unsigned long pa, u64 desc) { unsigned long pfn = pa >> PAGE_SHIFT; struct desc_struct *gdt_pent, d; @@ -2227,8 +2226,7 @@ long do_update_descriptor( struct exec_domain *ed; long ret = -EINVAL; - d.a = (u32)word1; - d.b = (u32)word2; + *(u64 *)&d = desc; LOCK_BIGLOCK(current->domain); diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index be6572622d..2002acd9ce 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -30,6 +30,7 @@ restore_all_guest: popq %r11 # CS cmpw $__GUEST_CS32,%r11 popq %r11 # RFLAGS + cli # No interrupts after stack switch popq %rsp # RSP je 1f sysretq @@ -112,8 +113,8 @@ ENTRY(syscall_enter) movq EDOMAIN_syscall_addr(%rbx),%rax movq %rax,TRAPBOUNCE_eip(%rdx) movw $0,TRAPBOUNCE_flags(%rdx) - pushq restore_all_guest(%rip) - jmp create_bounce_frame + call create_bounce_frame + jmp restore_all_guest /* %rbx: struct exec_domain */ hypercall: @@ -215,7 +216,7 @@ FLT11: movq %rax,8(%rsi) # ES FLT12: movq %rax,(%rsi) # DS 2: subq $16,%rsi movq XREGS_r11+8(%rsp),%rax -FLT13: movq %rax,(%rsi) # R11 +FLT13: movq %rax,8(%rsi) # R11 movq XREGS_rcx+8(%rsp),%rax FLT14: movq %rax,(%rsi) # RCX /* Rewrite our stack frame and return to guest-OS mode. */ diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 2d19d6f85f..931addf30b 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -249,6 +249,9 @@ long do_set_segment_base(unsigned int which, unsigned long base) { struct exec_domain *ed = current; + /* Canonicalise the base address. */ + base &= VADDR_MASK; + switch ( which ) { case SEGBASE_FS: @@ -266,6 +269,22 @@ long do_set_segment_base(unsigned int which, unsigned long base) wrmsr(MSR_GS_BASE, base, base>>32); break; + case SEGBASE_GS_USER_SEL: + __asm__ __volatile__ ( + " swapgs \n" + "1: movl %k0,%%gs \n" + " mfence; swapgs \n" /* AMD erratum #88 */ + ".section .fixup,\"ax\" \n" + "2: xorl %k0,%k0 \n" + " jmp 1b \n" + ".previous \n" + ".section __ex_table,\"a\"\n" + " .align 8 \n" + " .quad 1b,2b \n" + ".previous " + : : "r" (base&0xffff) ); + break; + default: return -EINVAL; } @@ -284,7 +303,7 @@ int check_descriptor(struct desc_struct *d) goto good; /* The guest can only safely be executed in ring 3. */ - if ( (b & _SEGMENT_DPL) != 3 ) + if ( (b & _SEGMENT_DPL) != _SEGMENT_DPL ) goto bad; /* All code and data segments are okay. No base/limit checking. */ diff --git a/xen/common/schedule.c b/xen/common/schedule.c index dddb96268a..fd825d2cfe 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -294,20 +294,14 @@ long do_sched_op(unsigned long op) } /* Per-domain one-shot-timer hypercall. */ -long do_set_timer_op(unsigned long timeout_hi, unsigned long timeout_lo) +long do_set_timer_op(s_time_t timeout) { - struct exec_domain *p = current; + struct exec_domain *ed = current; - rem_ac_timer(&p->timer); + rem_ac_timer(&ed->timer); - if ( (timeout_hi != 0) || (timeout_lo != 0) ) - { - p->timer.expires = ((s_time_t)timeout_hi<<32) | ((s_time_t)timeout_lo); - add_ac_timer(&p->timer); - } - - TRACE_5D(TRC_SCHED_SET_TIMER, p->domain->id, p->eid, p, timeout_hi, - timeout_lo); + if ( (ed->timer.expires = timeout) != 0 ) + add_ac_timer(&ed->timer); return 0; } diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 2a6c44d417..11efe50eda 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -92,6 +92,7 @@ #define SEGBASE_FS 0 #define SEGBASE_GS_USER 1 #define SEGBASE_GS_KERNEL 2 +#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ /* * int HYPERVISOR_switch_to_user(void) diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 43a2e87e02..7dc30c9dc6 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -158,20 +158,20 @@ * mfn: Machine frame number to be reassigned to the FD. * (NB. page must currently belong to the calling domain). */ -#define MMUEXT_PIN_L1_TABLE 0 /* ptr = MA of frame to pin */ -#define MMUEXT_PIN_L2_TABLE 1 /* ptr = MA of frame to pin */ -#define MMUEXT_PIN_L3_TABLE 2 /* ptr = MA of frame to pin */ -#define MMUEXT_PIN_L4_TABLE 3 /* ptr = MA of frame to pin */ -#define MMUEXT_UNPIN_TABLE 4 /* ptr = MA of frame to unpin */ -#define MMUEXT_NEW_BASEPTR 5 /* ptr = MA of new pagetable base */ -#define MMUEXT_TLB_FLUSH_LOCAL 6 /* ptr = NULL */ -#define MMUEXT_INVLPG_LOCAL 7 /* ptr = VA to invalidate */ -#define MMUEXT_TLB_FLUSH_MULTI 8 /* ptr = NULL; mask = VCPUs to flush */ -#define MMUEXT_INVLPG_MULTI 9 /* ptr = VA to inval.; mask = VCPUs */ +#define MMUEXT_PIN_L1_TABLE 0 +#define MMUEXT_PIN_L2_TABLE 1 +#define MMUEXT_PIN_L3_TABLE 2 +#define MMUEXT_PIN_L4_TABLE 3 +#define MMUEXT_UNPIN_TABLE 4 +#define MMUEXT_NEW_BASEPTR 5 +#define MMUEXT_TLB_FLUSH_LOCAL 6 +#define MMUEXT_INVLPG_LOCAL 7 +#define MMUEXT_TLB_FLUSH_MULTI 8 +#define MMUEXT_INVLPG_MULTI 9 #define MMUEXT_TLB_FLUSH_ALL 10 #define MMUEXT_INVLPG_ALL 11 #define MMUEXT_FLUSH_CACHE 12 -#define MMUEXT_SET_LDT 13 /* ptr = VA of table; val = # entries */ +#define MMUEXT_SET_LDT 13 #define MMUEXT_REASSIGN_PAGE 14 #define MMUEXT_NEW_USER_BASEPTR 15 -- 2.30.2